﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace SmlEngine.Sprites
{
    /// <summary>
    /// Defines a collection (of sprites?)
    /// </summary>
    /// <typeparam name="T">A type.</typeparam>
    public class SpriteSet<T> : IEnumerable<T>
    {
        private int visibleEnd;
        private int activeEnd;

        private List<T> items;

        /// <summary>
        /// How many elements there are.
        /// </summary>
        public int Count
        {
            get { return items.Count; }
        }

        /// <summary>
        /// How many visible elements there are.
        /// </summary>
        public int VisibleCount
        {
            get { return visibleEnd; }
        }

        /// <summary>
        /// How many active elements there are.
        /// </summary>
        public int ActiveCount
        {
            get { return visibleEnd - activeEnd; }
        }

        public T this[int index]
        {
            get { return items[index]; }
            set { items[index] = value; }
        }

        /// <summary>
        /// Returns a visible item.
        /// </summary>
        /// <param name="index">The index of the visible item.</param>
        /// <returns>A visible item.</returns>
        public T GetVisibleItem(int index)
        {
            return items[index];
        }

        /// <summary>
        /// Returns an active item.
        /// </summary>
        /// <param name="index">The index of the active item.</param>
        /// <returns>An active item.</returns>
        public T GetActiveItem(int index)
        {
            return items[index];
        }

        /// <summary>
        /// Constructs a new SpriteSet instance.
        /// </summary>
        public SpriteSet()
            : this(32) { }

        /// <summary>
        /// Constructs a new SpriteSet instance.
        /// </summary>
        /// <param name="capacity">The maximum capacity of this collection.</param>
        public SpriteSet(int capacity)
        {
            items = new List<T>(capacity);
        }

        /// <summary>
        /// Adds an item.
        /// </summary>
        /// <param name="item">The item to add.</param>
        public void Add(T item)
        {
            items.Add(item);
        }

        /// <summary>
        /// Adds an item.
        /// </summary>
        /// <param name="item">The item to add.</param>
        /// <param name="visibility">The item's visibility state.</param>
        public void Add(T item, Visibility visibility)
        {
            switch(visibility)
            {
                case Visibility.Visible:
                    items.Insert(0, item);
                    visibleEnd++;
                    return;

                case Visibility.Active:
                    items.Insert(visibleEnd + 1, item);
                    activeEnd++;
                    return;

                case Visibility.Exists:
                    items.Insert(activeEnd + 1, item);
                    return;

                case Visibility.DoesNotExist:
                    items.Remove(item);
                    return;
            }
        }

        public IEnumerator<T> GetEnumerator()
        {
            return items.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return items.GetEnumerator();
        }
    }
}
